#include "callcontrolpanel.h"
#include "ui_callcontrolpanel.h"
#include "../control/callcontroller.h"
#include "../osdglobal.h"
#include "../model/osdutilsmodel.h"
#include <QKeyEvent>
#include <QDebug>
#include "../control/msgpagecontroller.h"
#include "../remoteservice/statinfo.h"
#include "../model/osdremoteservicemodel.h"
#include "../event/senddocevent.h"
#include "../event/sendlocalevent.h"
#include "../event/sendsoundevent.h"
#include "../event/sendvedioevent.h"
#include "../event/showconnevent.h"
#include "../event/controlmenuevent.h"
#include "../sys/sysconfighandler.h"

#define UPDATE_CONNECTINFO_TIMEOUT  (1000)

CallControlPanel::CallControlPanel(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CallControlPanel)
{
    ui->setupUi(this);
    m_statList.clear();
    m_showlocal = true;
    m_doc = false;
    m_localvedio = false;
    m_sound = false;
    m_mode = false;
    m_remotevedio = false;
    m_info = false;
    m_currentWidget = NULL;

    ui->pbShowLocal->installEventFilter(this);
    ui->pbMic->installEventFilter(this);
    ui->pbVideo->installEventFilter(this);
    ui->pbContent->installEventFilter(this);
    ui->pbInfo->installEventFilter(this);
    ui->pbHalt->installEventFilter(this);
    ui->pbShowLocal->setFocus();
    initFocusOrder();

    connect(&CallController::instance(), SIGNAL(aquireFocusSig()), this, SLOT(aquireFocus()));
    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyModifyConfig(BaseResp)),
            this, SLOT(changeLocalShowSlot(BaseResp)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifySendContent(BaseResp)),
            this, SLOT(changeDocSlot(BaseResp)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifySendMic(BaseResp)),
            this, SLOT(changeSoundSlot(BaseResp)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifySendCamera(BaseResp)),
            this, SLOT(changeVedioSlot(BaseResp)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyStats(StatInfo)),
            this, SLOT(showConnInfoSlot(StatInfo)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyConfigInfo(ConfigInfo)),
            this, SLOT(configSlot(ConfigInfo)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyMicStatus(MicInfo)),
            this, SLOT(micStatusSlot(MicInfo)));

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyCameraStatus(CameraInfo)),
            this, SLOT(cameraStatusSlot(CameraInfo)));

    connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateConnectInfo()));

    connect(&OSDRemoteServiceModel::instance(), SIGNAL(notifyUpdateCellName(QString)), this, SLOT(updateCellNameSlot(QString)));
}

CallControlPanel::~CallControlPanel()
{
    delete ui;
}

void CallControlPanel::resetStatus()
{
    m_showlocal = true;
    m_doc = false;
    m_localvedio = false;
    m_sound = false;
    m_info = false;
}

void CallControlPanel::aquireFocus()
{
    m_currentWidget = m_currentWidget ? m_currentWidget:ui->pbShowLocal;
    QWidget *w = dynamic_cast<QWidget*>(m_currentWidget);
    if (w) w->setFocus();
}
QList<QList<QString> > CallControlPanel::statList() const
{
    return m_statList;
}

void CallControlPanel::setStatList(const QList<QList<QString> > &statList)
{
    m_statList = statList;
}

void CallControlPanel::initFocusOrder()
{
    QList<QObject *> orderlist;
    orderlist.clear();
    orderlist<< NULL << NULL << NULL << ui->pbMic;
    m_ctrlOrder.insert(ui->pbShowLocal, orderlist);

    orderlist.clear();
    orderlist<< NULL << NULL << ui->pbShowLocal << ui->pbVideo;
    m_ctrlOrder.insert(ui->pbMic, orderlist);

    orderlist.clear();
    orderlist<< NULL << NULL << ui->pbMic << ui->pbContent;
    m_ctrlOrder.insert(ui->pbVideo, orderlist);

    orderlist.clear();
    orderlist<< NULL << NULL << ui->pbVideo << ui->pbInfo;
    m_ctrlOrder.insert(ui->pbContent, orderlist);

    orderlist.clear();
    orderlist<< NULL << NULL << ui->pbContent << ui->pbHalt;
    m_ctrlOrder.insert(ui->pbInfo, orderlist);

    orderlist.clear();
    orderlist<< NULL << NULL << ui->pbInfo << NULL;
    m_ctrlOrder.insert(ui->pbHalt, orderlist);
}

bool CallControlPanel::eventFilter(QObject *o, QEvent *e)
{

    if (e->type() == QEvent::KeyRelease)
    {
        if (!this->isVisible())
        {
            e->accept();
            return true;
        }
        QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e);
        if (ke && (ke->key() == Qt::Key_Right
                   || ke->key() == Qt::Key_Down
                   || ke->key() == Qt::Key_Left))
        {
            if (!m_ctrlOrder.contains(o))
            {
                return false;
            }

            QObject *target = m_ctrlOrder.value(o).at(OSDUtilsModel::instance().keyIndex(ke->key()));
            if (target)
            {
                QWidget* w = qobject_cast<QWidget*>(target);
                if (w) w->setFocus();
                return true;
            }
        }

        if (ke && ke->key() == Qt::Key_Up)
        {
            //通知
            CallController::instance().loseFocus();
            return true;
        }
    }else if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress)
    {
        return true;
    }else if (e->type() == SendLocalEvent::eventType)
    {
        if (!this->isVisible())
        {
            e->accept();
            return true;
        }
        changeLocalShow();
        e->accept();
        return true;
    } else if (e->type() == SendSoundEvent::eventType)
    {
        if (!this->isVisible())
        {
            e->accept();
            return true;
        }
        changeSound();
        e->accept();
        return true;
    } else if (e->type() == SendVedioEvent::eventType)
    {
        if (!this->isVisible())
        {
            e->accept();
            return true;
        }
        changeVedio();
        e->accept();
        return true;
    } else if (e->type() == SendDocEvent::eventType)
    {
//        if (!this->isVisible())
//        {
//            e->accept();
//            return true;
//        }
        changeDoc();
        e->accept();
        return true;
    } else if (e->type() == ShowConnEvent::eventType)
    {
        if (!this->isVisible())
        {
            e->accept();
            return true;
        }
        showConnInfo();
        e->accept();
        return true;
    } else if (e->type() == ControlMenuEvent::eventType)
    {
        if (this->isVisible())
        {
            this->hide();
        }
        else
        {
            this->show();
        }
        e->accept();
        return true;
    }

    if (o == ui->pbShowLocal)
    {
        if (e->type() == QEvent::MouseButtonRelease
           || e->type() == QEvent::FocusIn
           || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                changeLocalShow();
            }
            else if (e->type() == QEvent::FocusIn)
            {
                ui->pbShowLocal->setProperty("selffocus", "1");
                m_currentWidget = ui->pbShowLocal;
            }
            else if (e->type() == QEvent::FocusOut)
            {
                ui->pbShowLocal->setProperty("selffocus", "0");
            }
            ui->pbShowLocal->style()->unpolish(ui->pbShowLocal);
            ui->pbShowLocal->style()->polish(ui->pbShowLocal);
            return true;
        }
    }
    else if (o == ui->pbMic)
    {
        if (e->type() == QEvent::MouseButtonRelease
           || e->type() == QEvent::FocusIn
           || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                changeSound();

            } else if (e->type() == QEvent::FocusIn)
            {
                ui->pbMic->setProperty("selffocus","1");
                m_currentWidget = ui->pbMic;
            } else if (e->type() == QEvent::FocusOut)
            {
                ui->pbMic->setProperty("selffocus","0");
            }
            ui->pbMic->style()->unpolish(ui->pbMic);
            ui->pbMic->style()->polish(ui->pbMic);
            return true;
        }
    }
    else if (o == ui->pbVideo)
    {
        if (e->type() == QEvent::MouseButtonRelease
           || e->type() == QEvent::FocusIn
           || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                changeVedio();
            }else if (e->type() == QEvent::FocusIn)
            {
                ui->pbVideo->setProperty("selffocus","1");
                m_currentWidget = ui->pbVideo;
            } else if (e->type() == QEvent::FocusOut)
            {
                ui->pbVideo->setProperty("selffocus","0");
            }
            ui->pbVideo->style()->unpolish(ui->pbVideo);
            ui->pbVideo->style()->polish(ui->pbVideo);
            return true;
        }
    }
    else if (o == ui->pbContent)
    {

        if (e->type() == QEvent::MouseButtonRelease
           || e->type() == QEvent::FocusIn
           || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                changeDoc();

            }else if (e->type() == QEvent::FocusIn)
            {
                ui->pbContent->setProperty("selffocus","1");
                m_currentWidget = ui->pbContent;
            } else if (e->type() == QEvent::FocusOut)
            {
                ui->pbContent->setProperty("selffocus","0");
            }
            ui->pbContent->style()->unpolish(ui->pbContent);
            ui->pbContent->style()->polish(ui->pbContent);
            return true;
        }
    }
    else if (o == ui->pbInfo)
    {
        if (e->type() == QEvent::MouseButtonRelease
                   || e->type() == QEvent::FocusIn
                   || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                showConnInfo();
            }else if (e->type() == QEvent::FocusIn)
            {
                ui->pbInfo->setProperty("selffocus","1");
                m_currentWidget = ui->pbInfo;
            } else if (e->type() == QEvent::FocusOut)
            {
                ui->pbInfo->setProperty("selffocus","0");
            }
            ui->pbInfo->style()->unpolish(ui->pbInfo);
            ui->pbInfo->style()->polish(ui->pbInfo);
            return true;
        }
    }
    else if (o == ui->pbHalt)
    {
        if (e->type() == QEvent::MouseButtonRelease
                   || e->type() == QEvent::FocusIn
                   || e->type() == QEvent::FocusOut)
        {
            if (e->type() == QEvent::MouseButtonRelease)
            {
                if (!this->isVisible())
                {
                    e->accept();
                    return true;
                }
                CallController::instance().exit();
                return true;
            }
            else if (e->type() == QEvent::FocusIn)
            {
                ui->pbHalt->setProperty("selffocus","1");
                m_currentWidget = ui->pbHalt;
            } else if (e->type() == QEvent::FocusOut)
            {
                ui->pbHalt->setProperty("selffocus","0");
            }
            ui->pbHalt->style()->unpolish(ui->pbHalt);
            ui->pbHalt->style()->polish(ui->pbHalt);
            return true;
        }
    }
    return false;
}

void CallControlPanel::changeLocalShowSlot(BaseResp rv)
{
    if (rv.getIsSuccess())
    {
        //改变按钮状态
        setShowLocalStatus(!m_showlocal);
    }
    else
    {
        MsgPageController::instance().showMsg(rv.getCodeString());
    }
}

void CallControlPanel::changeSoundSlot(BaseResp rv)
{
    if (rv.getIsSuccess())
    {
        //改变按钮状态
        setSoundStatus(!m_sound);
    }
    else
    {
        MsgPageController::instance().showMsg(rv.getCodeString());
    }
}

void CallControlPanel::changeVedioSlot(BaseResp rv)
{
    if (rv.getIsSuccess())
    {
        //改变按钮状态
        setVedioStatus(!m_localvedio);
    }
    else
    {
        MsgPageController::instance().showMsg(rv.getCodeString());
    }
}

void CallControlPanel::changeDocSlot(BaseResp rv)
{
    if (rv.getIsSuccess())
    {
        //改变按钮状态
        setDocStatus(!m_doc);
    }
    else
    {
        MsgPageController::instance().showMsg(rv.getCodeString());
    }
}

void CallControlPanel::showConnInfoSlot(StatInfo rv)
{
    if (rv.getIsSuccess())
    {
        m_info = !m_info;
        m_statList = rv.statList();
        CallController::instance().showInfo(true);
    }
    else
    {
        MsgPageController::instance().showMsg(rv.getCodeString());
        return;
    }
}

void CallControlPanel::updateCellNameSlot(QString data)
{
    //changeSubPageSlot(OSD::ViewGlobal::SUB_PAGE_MEET_LOADING);
    CallController::instance().updateCellName(data);
}

void CallControlPanel::configSlot(ConfigInfo rv)
{
    if (rv.getKey() == "call_rate")
    {
        SysConfigHandler::instance().setCallRate(rv.getValue());
    }
    else if (rv.getKey() == "show_local_video")
    {
        m_showlocal = (rv.getValue().compare("true") == 0);
        setShowLocalStatus(m_showlocal);
    }
}

void CallControlPanel::micStatusSlot(MicInfo rv)
{
    m_sound = rv.getEnable();
    setSoundStatus(m_sound);
}

void CallControlPanel::cameraStatusSlot(CameraInfo rv)
{
    m_localvedio = rv.getEnable();
    setVedioStatus(m_localvedio);
}

void CallControlPanel::changeLocalShow()
{
//    int vstr = (!m_showlocal) ? 1:0;
    OSDRemoteServiceModel::instance().modifyConfig("show_local_video",(!m_showlocal ? "true":"false"));
}

void CallControlPanel::changeSound()
{
    OSDRemoteServiceModel::instance().sendMic(!m_sound);
}

void CallControlPanel::changeVedio()
{
    OSDRemoteServiceModel::instance().sendCamera(!m_localvedio);
}

void CallControlPanel::changeDoc()
{
    OSDRemoteServiceModel::instance().sendContent(!m_doc);
}

void CallControlPanel::showConnInfo()
{
    if (m_info)
    {
        //通知关闭界面
        m_timer.stop();
        m_info = !m_info;
        m_statList.clear();
        CallController::instance().showInfo(false);
        return;
    }
    OSDRemoteServiceModel::instance().config("call_rate");
    OSDRemoteServiceModel::instance().stats();
    m_timer.start(UPDATE_CONNECTINFO_TIMEOUT);
}

void CallControlPanel::closeConnectInfo()
{
    m_timer.stop();
    m_info = false;
    m_statList.clear();
    CallController::instance().showInfo(false);
}

void CallControlPanel::hideEvent(QHideEvent *e)
{
    QWidget::hideEvent(e);
    closeConnectInfo();
}

void CallControlPanel::updateConnectInfo()
{
    OSDRemoteServiceModel::instance().stats();
}

void CallControlPanel::setFirstFocus()
{
    ui->pbShowLocal->setFocus();
}

void CallControlPanel::setSoundStatus(bool s)
{
    m_sound = s;
    ui->pbMic->setProperty("usestatus",s);
    ui->pbMic->style()->unpolish(ui->pbMic);
    ui->pbMic->style()->polish(ui->pbMic);
    ui->pbMic->update();
}

void CallControlPanel::setShowLocalStatus(bool s)
{
    m_showlocal = s;
    ui->pbShowLocal->setProperty("usestatus",s);
    ui->pbShowLocal->style()->unpolish(ui->pbShowLocal);
    ui->pbShowLocal->style()->polish(ui->pbShowLocal);
    ui->pbShowLocal->update();
}

void CallControlPanel::setVedioStatus(bool s)
{
    m_localvedio = s;
    ui->pbVideo->setProperty("usestatus",s);
    ui->pbVideo->style()->unpolish(ui->pbVideo);
    ui->pbVideo->style()->polish(ui->pbVideo);
    ui->pbVideo->update();
}

void CallControlPanel::setDocStatus(bool s)
{
    m_doc = s;
    ui->pbContent->setProperty("usestatus",s);
    ui->pbContent->style()->unpolish(ui->pbContent);
    ui->pbContent->style()->polish(ui->pbContent);
    ui->pbContent->update();
}
